﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

class Matrix
{
    private int[,] matrix;
    private int rows;    
    private int cols;

    public int Rows
    {
        get { return rows; }
        set { rows = value; }
    }

    public int Columns
    {
        get { return cols; }
        set { cols = value; }
    }
    
    public Matrix(int size)
    {
        this.matrix = new int[size,size];
        this.rows = size;
        this.cols = size;
        for (int i = 0; i < size; i++)
        {
            for (int j = 0; j < size; j++)
            {
                this.matrix[i, j] = 0;
            }
        }
    }

    public int this[int row, int col]
    {
        get
        {
            if (row < 0 || row >= this.matrix.GetLength(0) || col < 0 || col >= this.matrix.GetLength(1))
            {
                throw new IndexOutOfRangeException();
            }
            else
            {
                return this.matrix[row, col];
            }
        }
        set
        {
            if (row < 0 || row >= this.matrix.GetLength(0) || col < 0 || col >= this.matrix.GetLength(1))
            {
                throw new IndexOutOfRangeException();
            }
            else
            {
                this.matrix[row, col] = value;
            }
        }
    }

    public static Matrix operator +(Matrix matrix1, Matrix matrix2)
    {
        if ((matrix1.rows != matrix2.rows) || (matrix1.cols != matrix2.cols))
        {
            throw new ArgumentException("Both matrix must have equal size!");
        }
        else
        {
            Matrix result = new Matrix(matrix1.rows);
            for (int i = 0; i < matrix1.rows; i++)
            {
                for (int j = 0; j < matrix2.rows; j++)
                {
                    result[i, j] = matrix1[i, j] + matrix2[i, j];
                }
            }
            return result;
        }
    }

    public static Matrix operator -(Matrix matrix1, Matrix matrix2)
    {
        if ((matrix1.rows != matrix2.rows) || (matrix1.cols != matrix2.cols))
        {
            throw new ArgumentException("Both matrix must have equal size!");
        }
        else
        {
            Matrix result = new Matrix(matrix1.rows);
            for (int i = 0; i < matrix1.rows; i++)
            {
                for (int j = 0; j < matrix2.rows; j++)
                {
                    result[i, j] = matrix1[i, j] - matrix2[i, j];
                }
            }
            return result;
        }
    }

    public static Matrix operator *(Matrix matrix1, Matrix matrix2)
    {
        if ((matrix1.rows != matrix2.rows) || (matrix1.cols != matrix2.cols))
        {
            throw new ArgumentException("Both matrix must have equal size!");
        }
        else
        {
            Matrix resultMatrix = new Matrix(matrix1.rows);
            for (int row = 0; row < matrix1.rows; row++)
            {
                for (int col = 0; col < matrix2.rows; col++)
                {
                    resultMatrix[row, col] = 0;
                    for (int i = 0; i < resultMatrix.rows; i++)
                    {
                        resultMatrix[row, col] +=
                            matrix1[row, i] * matrix2[i, col];
                    }

                }
            }
            return resultMatrix;
        }
    }

    public override string ToString()
    {
        StringBuilder printedMatrix = new StringBuilder();
        for (int row = 0; row < this.rows; row++)
        {
            for (int col = 0; col < this.cols; col++)
            {
                printedMatrix.Append(this[row,col] + " ");
            }
            printedMatrix.Append("\n\r");
        }
        return printedMatrix.ToString();
    }
}

